﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace MolineSoftware
{
    //TODO: REmove the Transparency thing.

    /// <summary>
    /// Class: Used to execute <see cref="Action"/>s 
    /// </summary>
    public class FormThreader
    {
        #region | Constructor |
        public FormThreader(Form form)
        {
            this.form = form;
             this.MinOpacity = .50;

        }
        public FormThreader(Form form, int minOpacity)
            : this(form)
        {
            this.MinOpacity = minOpacity;
        }
        #endregion

        #region | Private Properties
        private Form form;
        private delegate void CallBackSetLoadStatus(bool loading);
        private delegate void CallBackAction(Action act);
        private delegate void CallBackAction2(Action act1, Action act2);
        private CallBackAction cbAction;
        private CallBackAction2 cbAction2;
        #endregion

        #region | Public Methods |
        public void Start(Action action)
        {
            cbAction = new FormThreader.CallBackAction(ExecuteAction);
            AsyncCallback callback = new AsyncCallback(CallBackHandler);
            cbAction.BeginInvoke(action, callback, new object[] { });
        }

        public void Start(Action action1, Action action2)
        {
            cbAction2 = new FormThreader.CallBackAction2(ExecuteAction);
            AsyncCallback callback = new AsyncCallback(CallBackHandler);
            cbAction2.BeginInvoke(action1, action2, callback, new object[] { });
        }
        #endregion

        #region | Public Properties |
        public delegate void CallBackVoid();

        /// <summary>
        /// Gets or Sets the Forms Opacity level when the form is loading/executing method
        /// </summary>
        public double MinOpacity { get; set; }
        #endregion

        #region | Private Methods |
        private void CallBackHandler(IAsyncResult ar)
        {
            cbAction.EndInvoke(ar);
            SetLoadStatus(false);
        }

        private void CallBackHandler2(IAsyncResult ar)
        {
            cbAction2.EndInvoke(ar);
            SetLoadStatus(false);
        }

        private void ExecuteAction(Action act)
        {
            SetLoadStatus(true);
            act.Invoke();
        }

        private void ExecuteAction(Action act1, Action act2)
        {
            SetLoadStatus(true);
            act1.Invoke();
            act2.Invoke();
        }

        private void SetLoadStatus(bool loading)
        {
            if (!form.InvokeRequired)
            {
                if (loading)
                {
                    form.Cursor = Cursors.WaitCursor;
                    //form.Opacity = this.MinOpacity;
                }
                else
                {
                    if (form.IsDisposed)
                        return;
                    form.Cursor = Cursors.Default;
                    //form.Opacity = 100;
                }
            }
            else
            {
                try
                {
                    CallBackSetLoadStatus cb = new FormThreader.CallBackSetLoadStatus(SetLoadStatus);
                    form.Invoke(cb, new object[] { loading });
                }
                catch { }
    

            }
          

        }
        #endregion
    }
}
